package com.projecthost.wizaz;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlListItem;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTable;
import com.gargoylesoftware.htmlunit.html.HtmlTableCell;
import com.gargoylesoftware.htmlunit.html.HtmlTableRow;
import com.projecthost.util.HtmlParser;
import com.projecthost.wizaz.model.Category;
import com.projecthost.wizaz.model.ProductBase;

public class WizazCategoryCrawler extends WizazCrawlerBase {

    private final static Logger logger = LoggerFactory.getLogger(WizazCategoryCrawler.class);

    public WizazCategoryCrawler(HtmlParser htmlParser, String mainWizazUrl) {
        super(htmlParser, mainWizazUrl);
    }

    public List<Category> getAllMainCategories() {
        HtmlPage htmlPage = htmlParser.getHtmlPageFromUrl(mainWizazUrl, false);
        HtmlElement catlistDiv = htmlPage.getElementById("catlist");
        return getCategories(catlistDiv);
    }

    private List<Category> getCategories(HtmlElement element) {
        @SuppressWarnings("unchecked")
        List<HtmlListItem> categoriesListElements = (List<HtmlListItem>) element.getByXPath("./ul/li");
        List<Category> categories = new ArrayList<Category>();
        for (HtmlListItem categoryElement : categoriesListElements) {
            Category category = getCategory(categoryElement);
            if (category != null) {
                categories.add(category);
            }
        }
        return categories;
    }

    private Category getCategory(HtmlListItem categoryElement) {
        HtmlAnchor categoryTitleAnchor = (HtmlAnchor) categoryElement.getByXPath("./a").get(0);
        String fullAHref = categoryTitleAnchor.getHrefAttribute();
        if (fullAHref.startsWith("kategoria.php")) {
            String categoryName = categoryTitleAnchor.getTextContent();
            List<Category> subCategories = getCategories(categoryElement);
            Category category = new Category(Category.getCategoryIdFromFullUrl(fullAHref), categoryName, subCategories);
            return category;

        } else {
            logger.warn("Not parsing category: " + categoryTitleAnchor);
            return null;
        }
    }

    public List<ProductBase> getProducts(String section, Integer categoryId) {
        return getProducts(section, categoryId, 1, true);
    }

    public List<ProductBase> getProducts(String section, Integer categoryId, Integer pageCount) {
        return getProducts(section, categoryId, pageCount, false);
    }

    private List<ProductBase> getProducts(String section, Integer categoryId, Integer pageCount, boolean withFollowingPages) {
        String pageUrl = Category.getFullUrl(categoryId, pageCount);
        HtmlPage firstProductPage = htmlParser.getHtmlPageFromUrl(mainWizazUrl + pageUrl, false);
        List<ProductBase> products = getProductsFromCurrentPage(firstProductPage);

        if (withFollowingPages) {
            String nextPageUrl = getNextPageUrl(firstProductPage);
            if (nextPageUrl != null) {
                List<ProductBase> productsOnNextPages = getProducts(section, categoryId, pageCount + 50, withFollowingPages);
                products.addAll(productsOnNextPages);
            }
        }
        return products;

    }

    private List<ProductBase> getProductsFromCurrentPage(HtmlPage firstProductPage) {
        HtmlTable productsTable = (HtmlTable) firstProductPage.getByXPath("//table[@class='products_list']").get(0);
        List<HtmlTableRow> productRows = productsTable.getElementsByAttribute("tr", "class", "list");
        List<ProductBase> productBases = new ArrayList<ProductBase>();
        for (HtmlTableRow productRow : productRows) {
            @SuppressWarnings("unchecked")
            List<HtmlTableCell> productCells = (List<HtmlTableCell>) productRow.getByXPath("./td");
            HtmlTableCell nameCell = productCells.get(1);
            HtmlAnchor nameAHref = (HtmlAnchor) nameCell.getElementsByTagName("a").get(0);
            String productUrl = nameAHref.getHrefAttribute();

            HtmlTableCell myHitCountCell = productCells.get(2);
            HtmlAnchor myHitAHref = (HtmlAnchor) myHitCountCell.getElementsByTagName("a").get(0);
            HtmlTableCell stars = productCells.get(3);

            float starsValue = getStarsValue(stars);
            HtmlTableCell reviewsNumber = productCells.get(4);
            String[] reviewsNumberSplit = reviewsNumber.getTextContent().trim().split(" ");

            ProductBase product = new ProductBase(ProductBase.getProductIdFromProductUrl(productUrl), nameAHref.getTextContent(),
                    Integer.valueOf(myHitAHref.getTextContent()), starsValue, Integer.valueOf(reviewsNumberSplit[0]));
            productBases.add(product);
        }
        return productBases;
    }

}
